package com.stormrage.edu.serv.learn.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.stormrage.constants.ErrCons;
import com.stormrage.edu.dao.exam.ExmScoreDao;
import com.stormrage.edu.dao.learn.LeaBunchApplyDao;
import com.stormrage.edu.dao.learn.LeaBunchDao;
import com.stormrage.edu.dao.learn.LeaBunchOperDao;
import com.stormrage.edu.dao.learn.LeaBunchUsuaDao;
import com.stormrage.edu.dao.learn.LeaStudentDao;
import com.stormrage.edu.dao.learn.LeaStudentSelectDao;
import com.stormrage.edu.dao.learn.LeaStudentVideoDao;
import com.stormrage.edu.dao.student.StuAcctDao;
import com.stormrage.edu.dao.student.StuInfoDao;
import com.stormrage.edu.serv.edu.EduMajorServ;
import com.stormrage.edu.serv.edu.EduVideoServ;
import com.stormrage.edu.serv.ent.EntEnterpriseServ;
import com.stormrage.edu.serv.exam.ExmScoreServ;
import com.stormrage.edu.serv.learn.LeaBunchApplyServ;
import com.stormrage.edu.serv.learn.LeaBunchServ;
import com.stormrage.edu.serv.learn.LeaStudentServ;
import com.stormrage.edu.serv.student.StuNoticeServ;
import com.stormrage.entity.edu.EduMajor;
import com.stormrage.entity.edu.EduVideo;
import com.stormrage.entity.ent.EntEnterprise;
import com.stormrage.entity.exam.ExmScore;
import com.stormrage.entity.excel.ExmOperExcel;
import com.stormrage.entity.excel.ExmUsuaExcel;
import com.stormrage.entity.learn.LeaBunch;
import com.stormrage.entity.learn.LeaBunchApply;
import com.stormrage.entity.learn.LeaStudent;
import com.stormrage.entity.learn.LeaStudentSelect;
import com.stormrage.entity.learn.rep.LeaBunchRep;
import com.stormrage.entity.learn.req.LeaBunchReq;
import com.stormrage.entity.learn.req.LeaStudentReq;
import com.stormrage.entity.learn.view.LeaStudentVideo;
import com.stormrage.entity.rep.ListRep;
import com.stormrage.entity.student.StuAcct;
import com.stormrage.entity.student.StuInfo;
import com.stormrage.entity.student.excel.StuAcctExcel;
import com.stormragetech.core.exception.StormrageTechException;
import com.stormragetech.core.util.DateUtil;
import com.stormragetech.core.util.ExcelUtil;

/**
 * @Title: LeaClassServImpl.java
 * @Package com.stormrage.edu.serv.learn.impl
 * @Description: 班级 Service
 * @author www.stormragetech.com
 * @date 2016年4月13日
 * @version V1.0
 */
@Service
public class LeaBunchServImpl implements LeaBunchServ {

	private static final Logger logger = LoggerFactory.getLogger(LeaBunchServImpl.class);

	@Value("#{constants['path.root']}")
	private String rootPath;

	@Value("#{constants['path.excel']}")
	private String excelPath;

	@Autowired
	private ExmScoreDao exmScoreDao;

	@Autowired
	private ExmScoreServ exmScoreServ;

	@Autowired
	private LeaBunchDao leaBunchDao;

	@Autowired
	private LeaBunchApplyDao leaBunchApplyDao;

	@Autowired
	private LeaBunchOperDao leaBunchOperDao;

	@Autowired
	private LeaBunchUsuaDao leaBunchUsuaDao;

	@Autowired
	private LeaStudentDao leaStudentDao;

	@Autowired
	private LeaStudentSelectDao leaStudentSelectDao;

	@Autowired
	private LeaStudentVideoDao leaStudentVideoDao;

	@Autowired
	private StuAcctDao stuAcctDao;

	@Autowired
	private StuInfoDao stuInfoDao;

	@Autowired
	private EduMajorServ eduMajorServ;

	@Autowired
	private EduVideoServ eduVideoServ;

	@Autowired
	private EntEnterpriseServ entEnterpriseServ;

	@Autowired
	private LeaBunchApplyServ leaBunchApplyServ;

	@Autowired
	private LeaStudentServ leaStudentServ;

	@Autowired
	private StuNoticeServ stuNoticeServ;

	@Override
	public void updateLockToSchedule(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 开始运行 ");

		leaBunchApplyServ.updateLockToSchedule(arg0);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 结束运行 ");

	}

	@Override
	public void updateLock() throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 开始运行 ");

		logger.debug("执行 >>>>>>>>> 1");

		List<LeaBunchApply> array = leaBunchApplyServ.queryByLock(2);
		if (null == array || array.size() <= 0) {
			logger.debug("需要初始化学员的班级为 【 0 】");
			return;
		}

		logger.debug("执行 >>>>>>>>> 2");
		String path = rootPath + excelPath + File.separator;
		logger.debug("path >>>>>>>>> " + path);
		Iterator<LeaBunchApply> it = array.iterator();
		while (it.hasNext()) {
			LeaBunchApply entity = it.next();

			// ------------------ 获取 excel 学员信息 ------------------
			List<StuAcctExcel> list = ExcelUtil.importExcel(path + entity.getExcel(), StuAcctExcel.class);
			if (null == list || list.size() <= 0) {
				logger.debug(" 出错位置 >>>>>>>>> 1");
				throw StormrageTechException.instance(ErrCons.SERV_ERR, "报名班级没有学员", StormrageTechException.ERR_APP,
						"【 LeaBunchServ 】-【 Update 】");
			}

			// ------------------ 创建学员账户及学籍 ------------------
			Iterator<StuAcctExcel> sit = list.iterator();
			while (sit.hasNext()) {

				StuAcctExcel stuAcctReq = sit.next();

				// ------------------ 创建学员账户 ------------------
				StuAcct acct = StuAcct.instance();
				Integer acctId = stuAcctDao.create(acct);
				acct = StuAcct.instance(acct, acctId);
				stuAcctDao.update(acct);

				// ------------------ 创建学员账户信息 ------------------
				StuInfo acctInfo = StuInfo.instance(stuAcctReq, acctId);
				stuInfoDao.create(acctInfo);

				// ------------------ 创建学员学籍 ------------------
				LeaStudent leaStu = LeaStudent.instance(acctId, entity.getBunchId(), entity.getApplyDate(), 0);
				Integer stuId = leaStudentDao.create(leaStu);

				// ------------------ 创建学员成绩 ------------------
				ExmScore score = ExmScore.instance(stuId);
				exmScoreDao.create(score);

				// ------------------ 创建学员课件 ------------------
				EduMajor major = eduMajorServ.queryByBunchId(entity.getBunchId());

				List<EduVideo> videoList = eduVideoServ.queryListByMajorId(major.getId());
				Iterator<EduVideo> iter = videoList.iterator();
				while (iter.hasNext()) {
					EduVideo video = iter.next();
					LeaStudentVideo stuVideo = LeaStudentVideo.instance(stuId, video.getId());
					leaStudentVideoDao.create(stuVideo);
				}

				// ------------------ 创建学员选课状态 ------------------
				LeaStudentSelect stuSelect = LeaStudentSelect.instance(stuId, 0);
				leaStudentSelectDao.create(stuSelect);
			}

			// ------------------ 创建学员账户及学籍 ------------------
			leaBunchApplyServ.updateLock(entity.getId());

		}

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 结束运行 ");

	}

	@Override
	public void update(final LeaBunchReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 开始运行 ");

		// ------------------ 获取班级信息 ------------------
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", arg0.getId());

		LeaBunchRep bunch = leaBunchDao.queryRepById(map);

		// ------------------ 获取 excel 学员信息 ------------------
		List<StuAcctExcel> list = ExcelUtil.importExcel(arg0.getPath() + bunch.getExcel(), StuAcctExcel.class);
		if (null == list || list.size() <= 0) {
			throw StormrageTechException.instance(ErrCons.SERV_ERR, "报名班级没有学员", StormrageTechException.ERR_APP,
					"【 LeaBunchServ 】-【 Update 】");
		}

		// ------------------ 创建学员账户及学籍 ------------------
		Iterator<StuAcctExcel> it = list.iterator();
		while (it.hasNext()) {

			StuAcctExcel stuAcctReq = it.next();

			// ------------------ 创建学员账户 ------------------
			StuAcct acct = StuAcct.instance();
			Integer acctId = stuAcctDao.create(acct);
			acct = StuAcct.instance(acct, acctId);
			stuAcctDao.update(acct);

			// ------------------ 创建学员账户信息 ------------------
			StuInfo acctInfo = StuInfo.instance(stuAcctReq, acctId);
			stuInfoDao.create(acctInfo);

			// ------------------ 创建学员学籍 ------------------
			LeaStudent leaStu = LeaStudent.instance(acctId, bunch.getId(), bunch.getApplyDate(), 0);
			Integer stuId = leaStudentDao.create(leaStu);

			// ------------------ 创建学员成绩 ------------------
			ExmScore score = ExmScore.instance(stuId);
			exmScoreDao.create(score);

			// ------------------ 创建学员课件 ------------------
			EduMajor major = eduMajorServ.queryByBunchId(arg0.getId());

			List<EduVideo> videoList = eduVideoServ.queryListByMajorId(major.getId());
			Iterator<EduVideo> iter = videoList.iterator();
			while (iter.hasNext()) {
				EduVideo video = iter.next();
				LeaStudentVideo stuVideo = LeaStudentVideo.instance(stuId, video.getId());
				leaStudentVideoDao.create(stuVideo);
			}

			// ------------------ 创建学员选课状态 ------------------
			LeaStudentSelect stuSelect = LeaStudentSelect.instance(stuId, 0);
			leaStudentSelectDao.create(stuSelect);

		}

		// ------------------ 创建学员账户及学籍 ------------------
		LeaBunch entity = LeaBunch.instance(bunch.getId(), 0);
		leaBunchDao.update(entity);

		// ------------------ 创建学员账户及学籍 ------------------
		leaBunchApplyServ.updateLock(bunch.getApplyId());

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 Update 】- 结束运行 ");

	}

	@Override
	public void delete(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 delete 】-【 STARTED 】");

		leaStudentServ.delete(arg0);

		leaBunchApplyServ.deletebyBunch(arg0);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", arg0);
		map.put("bunchId", arg0);

		leaBunchDao.delete(map);
		leaBunchApplyDao.deletebyBunch(map);
		leaStudentDao.delete(map);
		leaBunchOperDao.deleteByBunchId(map);
		leaBunchUsuaDao.deleteByBunchId(map);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 delete 】-【 COMPLETED 】");

	}

	@Override
	public void deleteByTermId(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 deleteByTermId 】-【 STARTED 】");

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", arg0);

		leaBunchDao.deleteByTermId(map);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 deleteByTermId 】-【 COMPLETED 】");

	}

	@Override
	public LeaBunch queryById(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryById 】-【 STARTED 】");

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", arg0);

		LeaBunch entity = leaBunchDao.queryById(map);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryById 】-【 COMPLETED 】");
		return entity;

	}

	@Override
	public ListRep queryListByLock(final LeaBunchReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListByLock 】- 开始运行 ");

		Map<String, Object> map = initQuery(arg0);

		Integer count = leaBunchDao.queryCountByLock(map);

		List<LeaBunchRep> array = leaBunchDao.queryListByLock(map);
		int seq = arg0.getPage().getStartPage() + 1;

		Iterator<LeaBunchRep> it = array.iterator();
		while (it.hasNext()) {
			LeaBunchRep entity = it.next();

			LeaStudentReq req = LeaStudentReq.instance(entity.getId(), 0, null);
			Integer stuCount = leaStudentServ.queryCountByBunchLock(req);

			entity = LeaBunchRep.instance(entity, seq, stuCount);
			seq++;
		}

		ListRep rep = ListRep.instance(count, array);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListByLock 】- 结束运行 ");
		return rep;

	}

	@Override
	public ListRep queryListForApply(final LeaBunchReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForApply 】- 开始运行 ");

		Map<String, Object> map = initQuery(arg0);

		Integer count = leaBunchDao.queryCountForApply(map);

		List<LeaBunchRep> array = leaBunchDao.queryListForApply(map);
		int seq = arg0.getPage().getStartPage() + 1;

		Iterator<LeaBunchRep> it = array.iterator();
		while (it.hasNext()) {
			LeaBunchRep entity = it.next();

			List<StuAcctExcel> list = ExcelUtil.importExcel(arg0.getPath() + entity.getExcel(), StuAcctExcel.class);
			logger.debug(" Excel 转化 List 为 " + array.toString());

			entity = LeaBunchRep.instance(entity, seq, list.size());
			seq++;
		}

		ListRep rep = ListRep.instance(count, array);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForApply 】- 结束运行 ");
		return rep;

	}

	@Override
	public ListRep queryListForSingle(final LeaBunchReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForSingle 】- 开始运行 ");

		Map<String, Object> map = initQuery(arg0);

		Integer count = leaBunchDao.queryCountForSingle(map);

		List<LeaBunchRep> array = leaBunchDao.queryListForSingle(map);
		int seq = arg0.getPage().getStartPage() + 1;

		logger.debug("caonimaa" + array.toString());

		Iterator<LeaBunchRep> it = array.iterator();
		while (it.hasNext()) {
			LeaBunchRep entity = it.next();

			LeaStudentReq req = LeaStudentReq.instance(entity.getId(), 1, null);
			Integer stuCount = leaStudentServ.queryCountByBunchLock(req);

			if (stuCount <= 0) {
				it.remove();
				count = count - 1;
			} else {
				entity = LeaBunchRep.instance(entity, seq, stuCount);
				seq++;
			}

		}

		logger.debug("caonimaa" + array.toString());

		ListRep rep = ListRep.instance(count, array);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForSingle 】- 结束运行 ");
		return rep;

	}

	@Override
	public ListRep queryListForLearn(final LeaBunchReq arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForLearn 】- 开始运行 ");

		Map<String, Object> map = initQuery(arg0);

		Integer count = leaBunchDao.queryCountForLearn(map);

		List<LeaBunchRep> array = leaBunchDao.queryListForLearn(map);
		int seq = arg0.getPage().getStartPage() + 1;

		Iterator<LeaBunchRep> it = array.iterator();
		while (it.hasNext()) {
			LeaBunchRep entity = it.next();

			logger.debug(" 班级返回为 " + entity.toString());

			List<LeaBunchApply> apply = leaBunchApplyServ.queryByBunchId(entity.getId());
			logger.debug("cadelei" + apply.toString());
			if (null == apply || apply.size() <= 0) {
				entity.setBunch("散员班级");
			} else {
				EntEnterprise ent = entEnterpriseServ.queryById(apply.get(0).getEntId());
				entity.setBunch(ent.getEnterprise());
			}

			logger.debug("cadelei" + apply.toString());
			LeaStudentReq req = LeaStudentReq.instance(entity.getId(), 0, null);
			Integer stuCount = leaStudentServ.queryCountByBunchLock(req);

			entity = LeaBunchRep.instance(entity, seq, stuCount);
			seq++;
		}

		ListRep rep = ListRep.instance(count, array);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForLearn 】- 结束运行 ");
		return rep;

	}

	@Override
	public List<LeaBunchRep> queryRepListForNotice() throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForLearn 】- 开始运行 ");

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("datetime", DateUtil.calDate(new Date(), Long.valueOf(-30)));

		List<LeaBunchRep> array = leaBunchDao.queryRepListForNotice(map);
		int seq = 1;

		Iterator<LeaBunchRep> it = array.iterator();
		while (it.hasNext()) {

			LeaBunchRep entity = it.next();

			Integer count = stuNoticeServ.queryCountByBunchId(entity.getId());
			entity = LeaBunchRep.instance(entity, seq, count);
			seq++;

		}

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 QueryListForLearn 】- 结束运行 ");
		return array;

	}

	@Override
	public Workbook queryOperExcel(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 queryOperExcel 】-【 STARTED 】 ");

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("bunchId", arg0);

		List<ExmOperExcel> array = leaBunchDao.queryOperListForExcel(map);

		ExportParams params = ExcelUtil.initParams("实操成绩单", "sheet", false);
		Workbook workbook = ExcelUtil.exportExcel(array, ExmOperExcel.class, params);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 queryOperExcel 】-【 COMPLETED 】 ");
		return workbook;

	}

	@Override
	public Workbook queryUsuaExcel(final Integer arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 queryUsuaExcel 】-【 STARTED 】 ");

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("bunchId", arg0);

		List<ExmUsuaExcel> array = leaBunchDao.queryUsuaListForExcel(map);

		ExportParams params = ExcelUtil.initParams("平时成绩单", "sheet", false);
		Workbook workbook = ExcelUtil.exportExcel(array, ExmUsuaExcel.class, params);

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 queryUsuaExcel 】-【 COMPLETED 】 ");
		return workbook;
	}

	@Override
	public void uploadUsua(final MultipartFile arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 uploadUsua 】-【 STARTED 】 ");

		try {

			InputStream input = arg0.getInputStream();
			List<ExmUsuaExcel> array = ExcelUtil.importExcel(input, ExmUsuaExcel.class);

			Iterator<ExmUsuaExcel> it = array.iterator();
			while (it.hasNext()) {
				ExmUsuaExcel entity = it.next();
				ExmScore score = exmScoreServ.queryByStuId(entity.getId());
				score.setUsua(entity.getScore());
				exmScoreServ.update(score);
			}

		} catch (IOException e) {
			throw StormrageTechException.instance(ErrCons.SERV_EXP, ErrCons.SERV_EXP_MSG,
					StormrageTechException.ERR_SYS, "【 LeaBunchServ 】- 【 uploadUsua 】", e);
		}

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 uploadUsua 】-【 COMPLETED 】 ");

	}

	@Override
	public void uploadOper(final MultipartFile arg0) throws StormrageTechException {

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 uploadUsua 】-【 STARTED 】 ");

		try {

			InputStream input = arg0.getInputStream();
			List<ExmOperExcel> array = ExcelUtil.importExcel(input, ExmOperExcel.class);
			input.close();

			Iterator<ExmOperExcel> it = array.iterator();
			while (it.hasNext()) {
				ExmOperExcel entity = it.next();
				ExmScore score = exmScoreServ.queryByStuId(entity.getId());
				score.setOper(entity.getScore());
				exmScoreServ.update(score);
			}

		} catch (IOException e) {
			throw StormrageTechException.instance(ErrCons.SERV_EXP, ErrCons.SERV_EXP_MSG,
					StormrageTechException.ERR_SYS, "【 LeaBunchServ 】- 【 uploadUsua 】", e);
		}

		logger.debug(" 【 Serv 】- 【 LeaBunchServ 】- 【 uploadUsua 】-【 COMPLETED 】 ");

	}

	private Map<String, Object> initQuery(LeaBunchReq arg0) {

		if (null == arg0)
			return null;

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("startPage", arg0.getPage().getStartPage());
		map.put("size", arg0.getPage().getSize());

		if (null != arg0.getType())
			map.put("type", arg0.getType());

		if (null != arg0.getLocked())
			map.put("locked", arg0.getLocked());

		if (null != arg0.getTermId())
			map.put("termId", arg0.getTermId());

		StringBuffer query = new StringBuffer("");

		if (null != arg0.getEnt() && !arg0.getEnt().isEmpty()) {
			query.append("e.enterprise LIKE :ent AND ");
			map.put("ent", "%" + arg0.getEnt() + "%");
		}

		if (null != arg0.getMajor() && !arg0.getMajor().isEmpty()) {
			query.append("d.major LIKE :major AND ");
			map.put("major", "%" + arg0.getMajor() + "%");
		}

		if (null != arg0.getApplyDateStart()) {
			query.append("b.apply_date > :start AND b.apply_date <= :end AND ");
			map.put("start", arg0.getApplyDateStart());
			map.put("end", arg0.getApplyDateEnd());
		}

		String sql = query.toString();
		if (null != sql && sql.length() > 0)
			map.put("query", " AND " + sql.substring(0, sql.length() - 4));
		else
			map.put("query", "");

		return map;
	}

}
